import { McData } from './McData';
import { ResManager } from './ResManager';
import { V2 } from './V2';
//import begin

const DEFAULT_RATE_INTERVAL = 1 / 30;

/**
 * 可以异步加载资源的Sprite
 */
export class McSprite extends Laya.Sprite {
    public url: string = null;
    protected loop: boolean = true;

    protected mcData: McData = null;
    protected rateInterval: number = DEFAULT_RATE_INTERVAL;
    protected frameCount: number = 0;
    protected frameDuration: number = -1;
    protected currentFrameIdx: number = 0;
    protected graphicsArray: Array<Laya.Graphics> = [];

    constructor(pos: V2 = V2.ZERO, zOrder: number = 0) {
        super();

        this.pos(pos.x, pos.y)
        this.zOrder = zOrder;
    }

    clear() {
        this.url = null;
        this.mcData = null;
        this.graphicsArray && (this.graphicsArray.length = 0);
        this.graphics = null;

        this.rateInterval = DEFAULT_RATE_INTERVAL;
        this.frameCount = 0;
        this.frameDuration = -1;
    }

    destroy() {
        this.clear();

        this.graphicsArray.length = 0;

        super.destroy();
    }

    /**
     * @param url 
     * @param loop 
     * @param force  是否强制渲染. 在对象使用池的时候 如果循环播放  必须在这里设置true 否则会return
     */
    play(url: string, loop: boolean = false, force?: boolean): boolean {
        if (url == this.url && loop && !force) {
            return false;
        }

        //判断是否同一个源
        if (this.url == url && this.graphicsArray.length > 0 && this.mcData != null) {
            return true;
        }

        this.url = url;
        this.loop = loop;

        this.mcData = ResManager.Singleton.getMcData(this.url);
        if (!this.mcData) {
            // 动画信息
            this.initGraphicsArray(null);
            this.loadRes(this.url);
            return false;
        } else {
            // 动画信息
            this.initGraphicsArray(this.mcData);
            return true;
        }
    }

    initGraphicsArray(mcData: McData) {
        if (!mcData) {
            this.rateInterval = DEFAULT_RATE_INTERVAL;
            this.frameCount = 0;
            this.frameDuration = -1;

            this.graphicsArray.length = 0;
            this.graphics = null;//当前帧擦除 
            return;
        }

        this.rateInterval = 1 / mcData.getFrameRate();
        this.frameCount = mcData.getFrameCount();
        this.frameDuration = this.rateInterval * this.frameCount;

        this.graphicsArray = this.createGraphicsArray(mcData);
        this.initGraphics();
    }

    protected initGraphics() {
        this.gotoFrame(0);
    }

    gotoFrame(frameIdx: number): void {
        frameIdx = _.clamp(frameIdx, 0, this.frameCount - 1);

        this.setGraphics(frameIdx);
    }

    private setGraphics(index: number) {
        this.graphics = this.graphicsArray[index];
    }

    loadRes(url: string) {
        let imgUrl: string = url.substr(0, url.lastIndexOf(".")) + ".png";

        let _url: string = url;
        let $this = this;

        return Promise.all([ResManager.Singleton.loadJsonP(url), ResManager.Singleton.loadImageP(imgUrl)])
            .then(result => {
                // 创建Graphics
                if (_url == $this.url) {
                    $this.mcData = ResManager.Singleton.getMcData(_url);
                    if (!$this.mcData) {
                        $this.mcData = $this.createMcData(_url, result[0], result[1]);
                        ResManager.Singleton.setMcData($this.mcData);
                    }
                    $this.initGraphicsArray($this.mcData);
                }
            }).catch(error => {
                console.debug("!!! " + url + "not found");
            });
    }

    createMcData(url: string, mcJson: any, textureAll: Laya.Texture): McData {
        // 创建McData
        let mc: any = null;
        for (let name in mcJson.mc) {
            mc = mcJson.mc[name];
            break;
        }

        let frameRate: number = mc.frameRate;
        let frameCount: number = mc.frames.length;

        let frameMap = {}

        for (let i = 0; i < frameCount; i++) {
            let frame = mc.frames[i];
            if (frame.res) {
                // 防止frame是空白帧
                let resData = mcJson.res[frame.res];
                frameMap[url + "#" + i] = Laya.Texture.create(textureAll, resData.x, resData.y, resData.w, resData.h, frame.x, frame.y);
            }
        }

        return new McData(url, frameRate, frameCount, frameMap);
    }

    createGraphicsArray(mcData: McData): Array<Laya.Graphics> {
        if (!this.graphicsArray) this.graphicsArray = [];
        else this.graphicsArray.length = 0;

        for (let i = 0; i < this.mcData.getFrameCount(); i++) {
            let graphics: Laya.Graphics = new Laya.Graphics();
            graphics.drawImage(this.mcData.getFrame(i), 0, 0);
            this.graphicsArray.push(graphics);
        }

        return this.graphicsArray;
    }

    /********************************************************************************
     * Getter && Setter
     ********************************************************************************/
    getMcData(): McData {
        return this.mcData;
    }

    getTotalFrame(): number {
        return this.frameCount;
    }

    // 获得单次动画的最大持续时间
    getDuration(): number {
        return this.frameDuration;
    }

    getRateInterval(): number {
        return this.rateInterval;
    }
}